#ifndef _ESP8266_H
#define _ESP8266_H

#ifdef __cplusplus
extern "C" {
#endif


#include "wifi_device.h"
#include "wifi_hotspot_config.h"
#include "wifi_hotspot.h"
#include "stdint.h"

#define WIFI_DEBUG              1
#define AT_USART_PORT           2
#define WIFI_TIMEOUT            15                 // 应答延时 单位 s
#define WIFI_SSID               "Mate 30 Pro 5G"
#define WIFI_PASSWD             "123321123"
//#define WIFI_SSID               "CMCC-F3JZ"
//#define WIFI_PASSWD             "S3LL5DYY"


#define WIFI_RESET              "AT+RST"            // 复位
#define WIFI_GET_MODE           "AT+CWMODE?"        // 查询当前设备模式
#define WIFI_SET_MODE           "AT+CWMODE="        // 设置设备模式
#define WIFI_GET_SLEEP          "AT+SLEEP?"         // 查询设备休眠模式
#define WIFI_SET_SLEEP          "AT+SLEEP="         // 设置休眠模式

#define STA_SCAN_HOTSPOT        "AT+CWLAP"          // station模式下: 扫描当前热点列表
#define STA_SCAN_HOTSPOT_CUSTOM "AT+CWLAP="         // station模式下: 扫描特定的热点列表 "ssid","bssid"
#define STA_JOIN_HOTSPOT        "AT+CWJAP_DEF="     // station模式下: 加入某热点
#define STA_EXIT_HOTSPOT        "AT+CWQAP"          // station模式下: 退出当前加入的热点
#define STA_CURRENT_HOTSPOT     "AT+CWJAP_CUR?"     // station模式下: 当前加入的热点信息
#define STA_GET_MAC             "AT+CIPSTAMAC?"     // station模式下: 本机MAC
#define STA_SET_MAC             "AT+CIPSTAMAC="     // station模式下: 设置本机MAC
#define STA_GET_IP              "AT+CIPSTA?"        // station模式下: 本机IP
#define STA_SET_IP              "AT+CIPSTA="        // station模式下: 设置本机IP
#define SAT_AUTOLINK            "AT+CWAUTOCONN"     // station模式下: 开机启动连接
#define STA_CONNECT             "AT+CIPSTART="      // station模式下: 建立TCP/UDP连接
#define STA_SEND                "AT+CIPSEND="       // station模式下: 发送数据
#define STA_RECV                "+IPD"              // station模式下: 接收数据
#define STA_DISCONNECT          "AT+CIPCLOSE"       // station模式下: 关闭连接

#define AP_GET_MAC              "AT+CIPAPMAC?"      // ap模式下: 查询本机MAC
#define AP_SET_MAC              "AT+CIPAPMAC="      // ap模式下: 设置本机MAC
#define AP_GET_IP               "AT+CIPAP?"         // ap模式下: 查询本机IP
#define AP_SET_IP               "AT+CIPAP="         // ap模式下: 设置本机IP
#define AP_GET_PARAM            "AT+CWSAP_CUR?"     // ap模式下: 查询本机当前热点的配置信息
#define AP_SET_PARAM            "AT+CWSAP_DEF="     // ap模式下: 设备本机热点配置信息
#define AP_LIST_CLIENT          "AT+CWLIF"          // ap模式下: 当前已经加入的各个设备信息
#define AP_SET_DHCP             "AT+CWDHCP"         // ap模式下: 设置DHCP    

#define RSSI_LEVEL_4_2_G (-65)
#define RSSI_LEVEL_3_2_G (-75)
#define RSSI_LEVEL_2_2_G (-82)
#define RSSI_LEVEL_1_2_G (-88)
#define RSSI_LEVEL_4_5_G (-65)
#define RSSI_LEVEL_3_5_G (-72)
#define RSSI_LEVEL_2_5_G (-79)
#define RSSI_LEVEL_1_5_G (-85)

#define CHANNEL_80211B_ONLY 14
#define FREQ_OF_CHANNEL_1 2412
#define FREQ_OF_CHANNEL_80211B_ONLY 2484
#define WIFI_MIN_CHANNEL 1
#define WIFI_FREQ_INTERVAL 5


typedef enum {
    STA = 1,
    AP,
    ATA_AP,
} NetModeType;

typedef enum {
    TCP = 1,
    UDP,
} ProtocolType;

typedef struct {
    /** Network name of the station */
    char name[128];
    /** MAC address. For its length, see {@link WIFI_MAC_LEN}. */
    unsigned char macAddress[6];
    /** IP address of the station */
    unsigned int ipAddress;
    unsigned short disconnectedReason;
} ClientInfo;

typedef struct{
    ProtocolType protocol;
    char serverIP[16];
    unsigned short port;
}ServerInfo;


void mac_str2hex(char *dst, char *src);
void mac_hex2str(char *dst, char *src);
uint32_t ip_to_int(char *ip);
void int_to_ip(char *ip_str, uint32_t ip_int);
unsigned int ChannelToFrequency(unsigned int channel);
unsigned int FrequencyToChannel(unsigned int frequency);

void ScanCB(WifiErrorCode res);
void ConnectCB(WifiErrorCode res);
void DisConnectCB(WifiErrorCode res);
void HotspotChangeCB(WifiErrorCode res);
void HotspotStaJoinCB(StationInfo *info);
void HotspotStaLeaveCB(StationInfo *info);

int WifiUartInit();
WifiErrorCode WifiReset();
int ESP8266_GenerateSSIDAndPassword(char *dst, char *src);
void ParseWifiScanResult(char *buf, WifiScanInfo *info);
void StationListener();
char SendWifiCommand(char *cmd, char *args);
int8_t WaitWifiResponse(char *cmd, char *result, uint32_t timeout);
void PrintWifiError(WifiErrorCode res);

WifiErrorCode ESP8266_ConnectTo(char *ip, uint16_t port, ProtocolType type);
WifiErrorCode ESP8266_DisConnect();
int ESP8266_Send(char *msg, int msglen);
// 由于串口收到的数据是 +IPD,3:123 类型，因此需要将数据解析到另一个队列中
int ESP8266_Recv(char *recvBuf, int recvLen, uint32_t timeout);

#ifdef __cplusplus
}
#endif

#endif /* _ESP8266_H */
